package framework

import (
	"MoSkeleton/framework/core"
	"MoSkeleton/framework/core/config/properties"
	"MoSkeleton/framework/core/config/properties_redis"
	"MoSkeleton/framework/core/translater"
	"github.com/allegro/bigcache/v3"
	"github.com/bwmarrin/snowflake"
	"github.com/gin-gonic/gin"
	"github.com/golang/groupcache/singleflight"
	"github.com/redis/go-redis/v9"
	"go.uber.org/zap"
	"gorm.io/gorm"
	"os"
)

var (
	WorkDir                 string
	MoLogger                *zap.Logger = new(zap.Logger)
	SyncGroup                           = &singleflight.Group{}
	BeforeInitContainerInst             = core.NewInitContainer[core.BeforeInitSystem]()
	//该容器可用于注册初始化framework外的系统
	InitContainerInst  = core.NewInitContainer[core.DoInitSystem]()
	AfterContainerInst = core.NewInitContainer[core.AfterInitSystem]()
)
var (
	Translater    *translater.Translater
	SnowflakeNode *snowflake.Node

	ConfigContainerInst *ConfigContainer
	MO_DBORM            *gorm.DB
	MoRedis             redis.UniversalClient

	GinRouter  *gin.Engine
	LocalCache *bigcache.BigCache
)

var (
	SnowflakeProperty *properties.SnowflakeProperty
	Profile           *properties.Profile
	RedisProperties   *properties_redis.RedisProperty
)

func BeforeInitFramework() {
	WorkDir, _ = os.Getwd()
	translater.Profile = Profile
	ConfigContainerInst = new(ConfigContainer)
	if err := ConfigContainerInst.BeforeInitSystem(); err != nil {
		MoLogger.Info("before framework Error", zap.Error(err))
		return
	}
	doBeforeSys()
}

func DoInitFramework() bool {
	if err := ConfigContainerInst.OnInitSystem(); err != nil {
		MoLogger.Info("init framework Error", zap.Error(err))
		return false
	}
	doInitSys()
	return true
}

func AfterInitFramework() {
	doAfterSys()
}

func doBeforeSys() {
	for beforeInitSys := range BeforeInitContainerInst.Iterator() {
		err := beforeInitSys.OnBeforeInitSystem()
		if err != nil {
			MoLogger.Info("Init System Error", zap.Error(err))
		}
	}
}
func doInitSys() {
	for doInitSys := range InitContainerInst.Iterator() {
		err := doInitSys.OnInitSystem()
		if err != nil {
			MoLogger.Info("Init System Error", zap.Error(err))
		}
	}
}

func doAfterSys() {
	for afterInitSys := range AfterContainerInst.Iterator() {
		err := afterInitSys.OnAfterInitSystem()
		if err != nil {
			MoLogger.Info("after System Error", zap.Error(err))
		}
	}
}
